import java.io.*;
import java.util.*;

public class ParcelList extends Observable {

	private ArrayList<Parcel> parcelList;

	// Construct: create an empty ArrayList to store Parcels
	public ParcelList() {
		parcelList = new ArrayList<Parcel> ();
	}

	/**
	 * Add Parcel to the list
	 * @param s Parcel object to add
	 */
	private void add(Parcel s) {
		parcelList.add(s);
		
		Logger.INSTANCE.appendLog("main", "Parcel '"+s.getId()+"' entered the depot\n");
		
		// Tell observers the list of parcels has changed
		try {
			this.setChanged();
			this.notifyObservers();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Add Parcel to the list from basic inputs
	 * @param s Parcel object to add
	 */
	public void addParcel(String parcelId, int days, int weight, String dimensionsString) {
		// Parcel Dimensions - String
		// Processes string which contains length/width/height of parcel
		// separated by " x ", creates a Dimensions object 
		Dimensions dimensions = new Dimensions(dimensionsString);

		//create Parcel object and add to the list
		Parcel s = new Parcel(parcelId, days, weight, dimensions);
		this.add(s);
	}

	/**
	 * Returns a list of all Parcels in the list
	 * including everything we know about each, one per line
	 * @return String representation of Parcel list
	 */
	public String outputParcels()
	{
		// Print "table" header to show columns
		String report = String.format("%-6s", "ID");
		report += String.format("%-6s", "Days");
		report += String.format("%-8s", "Weight");
		report += String.format("%-15s", "Dimensions") + "\n";

		for (Parcel s  : parcelList){
			report += String.format("%-6s", s.getId());
			report += String.format("%-6s", s.getDays() );
			report += String.format("%-8s", s.getWeight() );
			report += String.format("%-15s", s.getDimensionsString() );
			report += "\n";
		}
		return report;
	}

	/**
	 * Returns number of Parcels in the list
	 * @return int size of Parcel list
	 */
	public int getSize() {
		return parcelList.size();
	}

	/**
	 * Returns the Parcel object at specified ArrayList index
	 * @param index int containing the index of the Parcel to get
	 * @return Parcel object or null if incorrect index
	 */
	public Parcel getAtIndex(int index) {
		return parcelList.get(index);
	}

	/**
	 * Returns the Parcel object with a specified Parcel ID
	 * @param parcelId String containing the parcelId (numerical or otherwise) of the Parcel to find
	 * @return Parcel object found, or null if none found
	 */
	public Parcel findByParcelId(String parcelId)
	{
		for (Parcel s : parcelList)
		{
			if (s.getId().equals(parcelId)) {
				return s;
			}
		}
		return null;
	}

	/**
	 * Returns true if the parcel with specified Parcel ID was found and removed, false otherwise
	 * @param parcelId String containing the parcelId (numerical or otherwise) of the Parcel to remove
	 * @return true if removed, or false if not
	 */
	public boolean removeParcel(String parcelId)
	{
		// If parcelId doesn't exist, return false
		if(findByParcelId(parcelId) == null) return false;

		Logger.INSTANCE.appendLog("main", "Parcel '"+parcelId+"' left the depot\n");
		
		ArrayList<Parcel> parcelListNew = new ArrayList<Parcel> ();

		for (Parcel parcel : parcelList) {
			if ( parcel.getId().equals(parcelId) == false ) {
				parcelListNew.add(parcel);
			}
		}

		parcelList = parcelListNew;

		// Tell observers the list of parcels has changed
		try {
			this.setChanged();
			this.notifyObservers();
		} catch (Exception e) {
			e.printStackTrace();
		}	

		return true;
	}

	/** reads file with given name, extracting Parcel data
	 * Blank lines are skipped
	 * @param filename the name of the input file
	 */
	public void readFile(String filename) throws FileNotFoundException {
		InputStream is = getClass().getResourceAsStream(filename);
		Scanner scanner = new Scanner(is);
		while (scanner.hasNextLine()) {
			//read first line and process it
			String inputLine = scanner.nextLine();
			if (inputLine.length() != 0) {//ignored if blank line
				//create Parcel object and add to the list
				Parcel s = new Parcel(inputLine);
				this.add(s);
			}
		}
		scanner.close();

		// Tell observers the queue has changed since we just added a batch of customers
		try {
			this.setChanged();
			this.notifyObservers();
		} catch (Exception e) {
			e.printStackTrace();
		}		
	}

}